{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练 习 5.1:实现函数infer_matrix(n,transformation)，接收一个维度参数(比如2或3)和一个线性向量变换的函数参数，返回$n \\times n $方阵(一个n元组的元组的数字集，表示线性变换的矩阵)。当然，只有当输入变换是线性时，输出才有意义;否则，表示的将是一个完全不同的函数!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def infer_matrix(n,transformation): \n",
    "  def standard_basis_vertor(i):\n",
    "    return tuple(1 if j==i else 0 for j in range(1,n+1)) # 生成第 i 个标准基向量（从 0 开始索引）。\n",
    "  \n",
    "  standard_basis = [standard_basis_vertor(i) for i in range(1,n+1)] # 生成标准基向量列表。\n",
    "  cols = [transformation(v) for v in standard_basis] # 生成列向量列表。\n",
    "\n",
    "  return tuple(zip(*cols))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((0, -1), (1, 0))\n"
     ]
    }
   ],
   "source": [
    "## 验证代码\n",
    "def rotate_90(v):\n",
    "    x, y = v\n",
    "    return (-y, x)  # 逆时针旋转90°的变换\n",
    "\n",
    "# 手动计算的旋转矩阵应为: [[0, -1], [1, 0]]\n",
    "matrix = infer_matrix(2, rotate_90)\n",
    "print(matrix)  # 应输出 ((0, 1), (-1, 0))（注意行列可能转置）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 0, 0)\n",
      "(0, 1, 0)\n",
      "(0, 0, 1)\n"
     ]
    }
   ],
   "source": [
    "nn = 3\n",
    "for i in range(1,nn+1):\n",
    "    print(standard_basis_vertor(i))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.2:如下2x2矩阵与二维向量的乘积结果是什么?\n",
    "\n",
    "$\\begin{pmatrix}\n",
    "1.3 & 0.7 \\\\\n",
    "6.5 & 3.2\n",
    "\\end{pmatrix}\n",
    "\\begin{pmatrix}\n",
    "-2.5 \\\\\n",
    "0.3\n",
    "\\end{pmatrix}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$1. -2.5 \\times 1.3 + 0.3 \\times 0.7 = -3.46$\n",
    "\n",
    "$2. -2.5 \\times 6.5 + 0.3 \\times 3.2 = -15.29$\n",
    "\n",
    "$\\begin{pmatrix}\n",
    "1.3 & 0.7 \\\\\n",
    "6.5 & 3.2\n",
    "\\end{pmatrix}\n",
    "\\begin{pmatrix}\n",
    "-2.5 \\\\\n",
    "0.3\n",
    "\\end{pmatrix}$ = $\\begin{pmatrix} -3.46 \\\\ -15.29 \\end{pmatrix}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.3(小项目):实现random_matrix函数，用随机整数项生成指定大小的矩阵。使用该函数生成5对3x3矩阵。手动将每对矩阵相乘(用于练习)，然后使用matrix_multiply函数来检查结果是否一致。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((3, 9, 5), (2, -2, 9), (-8, 0, -6))"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import sys\n",
    "sys.path.append('E:/CodeFile/python/mathematics-for-programmers/pyfile')\n",
    "from ExternalTools.vectors import *\n",
    "import random\n",
    "\n",
    "## 矩阵相乘\n",
    "def matrix_multiply(a, b):\n",
    "  return tuple(\n",
    "    tuple(dot(row,col) for col in zip(*b)) for row in a\n",
    "  )\n",
    "\n",
    "## 用随机整数项生成指定大小的矩阵\n",
    "def random_matrix(n):\n",
    "  return tuple(\n",
    "    tuple(random.randint(-10,10) for _ in range(n)) for _ in range(n)\n",
    "  )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((-22, 141, 78), (-14, -53, -32), (20, -150, -160))"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# for i in range(5):\n",
    "#   print(random_matrix(3))\n",
    "\n",
    "matrix_multiply(((5, -9, -8), (-5, 1, 5), (10, 10, 10)),((0, 1, -4), (6, -8, -2), (-4, -8, -10)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{aligned}\n",
    "\n",
    "&\\begin{pmatrix}\n",
    "\n",
    "5 & -9 & -8 \\\\\n",
    "5 & 1 & 5 \\\\\n",
    "10 & 10 & 10\n",
    "\n",
    "\\end{pmatrix}\n",
    "\n",
    "\\times\n",
    "\n",
    "\\begin{pmatrix}\n",
    "\n",
    "0 & 1 & -4 \\\\\n",
    "\n",
    "6 & -8 & -2 \\\\\n",
    "\n",
    "-4 & -8 & -10\n",
    "\\end{pmatrix}\n",
    "\n",
    "\\\\\n",
    "\n",
    "&= \\begin{pmatrix}\n",
    "\n",
    "(5×0)+(-9×6)+(-8×-4) & (5×1)+(-9×-8)+(-8×-8) & (5×-4)+(-9×-2)+(-8×-10) \\\\\n",
    "\n",
    "(-5×0)+(1×6)+(5×-4) & (-5×1)+(1×-8)+(5×-8) & (-5×-4)+(1×-2)+(5×-10) \\\\\n",
    "\n",
    "(10×0)+(10×6)+(10×-4) & (10×1)+(10×-8)+(10×-8) & (10×-4)+(10×-2)+(10×-10)\n",
    "\n",
    "\\end{pmatrix}\n",
    "\n",
    "\\\\\n",
    "\n",
    "&= \\begin{pmatrix}\n",
    "\n",
    "0-54+32 & 5+72+64 & -20+18+80 \\\\\n",
    "\n",
    "0+6-20 & -5-8-40 & 20-2-50 \\\\\n",
    "\n",
    "0+60-40 & 10-80-80 & -40-20-100\n",
    "\n",
    "\\end{pmatrix}\n",
    "\n",
    "\\\\\n",
    "\n",
    "&= \\begin{pmatrix}\n",
    "\n",
    "22 & 141 & 78 \\\\\n",
    "14 & -53 & -32 \\\\\n",
    "20 & -150 & -160\n",
    "\n",
    "\\end{pmatrix}\n",
    "\n",
    "\\end{aligned}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.4:对于上一个练习中的每一组矩阵，按相反的顺序相乘，得到的结果一样吗?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((-45, -39, -35), (50, -82, -108), (-80, -72, -108))"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "matrix_multiply(((0, 1, -4), (6, -8, -2), (-4, -8, -10)),((5, -9, -8), (-5, 1, 5), (10, 10, 10)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不一样，因为矩阵乘法不具备可交换性：AB不等于BA。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.5:在二维或三维中，有一个枯燥但重要的向量变换，叫作恒等变换，它接收一个向量并返回相同的向量。这种变换是线性的，因为它接收任意向量和、标量乘积或线性组合，并返回相同的东西。在二维和三维中，分别表示恒等变换的矩阵是什么?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "标准基向量：\n",
    "\n",
    "$$\n",
    "I_2 = \n",
    "\\begin{pmatrix}\n",
    "1 & 0\\\\\n",
    "0 & 1\n",
    "\\end{pmatrix}\n",
    ",\n",
    "I_3 = \n",
    "\\begin{pmatrix}\n",
    "1 & 0 &0\\\\\n",
    "0 & 1 & 0\\\\\n",
    "0 & 0 & 1\n",
    "\\end{pmatrix}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.6:对所有定义茶壶的向量应用矩阵((2,1,1)，(1,2,1)，(1,1,2))。茶壶会发生什么情况，为什么?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当对茶壶的所有向量应用矩阵 \\( $M = \\begin{pmatrix} 2 & 1 & 1 \\\\ 1 & 2 & 1 \\\\ 1 & 1 & 2 \\end{pmatrix}$ \\) 时，茶壶会发生**均匀缩放和拉伸变形**。具体分析如下：\n",
    "\n",
    "#### **1. 矩阵分解**\n",
    "该矩阵可以分解为：\n",
    " $M = I + S = \\begin{pmatrix} 1 & 0 & 0 \\\\ 0 & 1 & 0 \\\\ 0 & 0 & 1 \\end{pmatrix} + \\begin{pmatrix} 1 & 1 & 1 \\\\ 1 & 1 & 1 \\\\ 1 & 1 & 1 \\end{pmatrix}$ \n",
    "- **\\( I \\)**：单位矩阵（保持原始形状）。\n",
    "- **\\( S \\)**：所有元素为1的矩阵（均匀拉伸）。\n",
    "\n",
    "#### **2. 变换效果**\n",
    "- **缩放**：对角线元素为2，表示沿每个坐标轴方向**放大2倍**。\n",
    "- **拉伸**：非对角线元素为1，表示在 \\( x \\)、\\( y \\)、\\( z \\) 方向之间产生**耦合拉伸**（即一个坐标的变化会带动其他坐标变化）。\n",
    "\n",
    "数学上，对任意向量 $\\mathbf{v} = (x, y, z)$ ：\n",
    "$M\\mathbf{v} = \\begin{pmatrix} 2x + y + z \\\\ x + 2y + z \\\\ x + y + 2z \\end{pmatrix}$ \n",
    "这会使得茶壶的顶点向空间对角线方向  (1,1,1)  拉伸。\n",
    "\n",
    "#### **3. 几何解释**\n",
    "- **体积变化**：矩阵的行列式 \\( $\\det(M) = 4$ \\)，表示茶壶体积会**变为原来的4倍**。\n",
    "- **对称性**：矩阵对称（\\($ M = M^T$ \\)），说明变换是均匀的，不会产生扭曲或旋转。\n",
    "- **特征分析**：\n",
    "  - 特征值为 \\( $\\lambda_1 = 1$ \\)(对应方向垂直于 (1,1,1))， $\\lambda_2 = 4$ （对应方向  (1,1,1)）。\n",
    "  - 茶壶会沿空间对角线方向显著拉伸。\n",
    "\n",
    "#### **4. 直观效果**\n",
    "- **茶壶变大**：整体尺寸放大。\n",
    "- **形状变形**：茶壶的对称性会被破坏，壶嘴、把手等部分会沿 (1,1,1) 方向拉长，看起来像被“斜向拉伸”。\n",
    "\n",
    "#### **5. 为什么？**\n",
    "这种变换是**线性变换**的典型例子：\n",
    "1. **非对角元素**导致坐标耦合，打破各向同性。\n",
    "2. **对角优势**（对角线元素大于其他）使得形状不至于完全坍缩，但仍会偏向主拉伸方向。\n",
    "\n",
    "### 总结\n",
    "茶壶会变成一个**体积更大、沿空间对角线方向拉伸**的变形体，类似从正球体变为椭球体的效果。这种变换在图形学中可用于模拟**弹性形变**或**各向异性缩放**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pygame 2.6.1 (SDL 2.28.4, Python 3.8.20)\n",
      "Hello from the pygame community. https://www.pygame.org/contribute.html\n"
     ]
    }
   ],
   "source": [
    "!python matrix_transform_teapot.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.7:使用两个嵌套推导式以不同的方式实现multiply_matrix_vector:一个遍历矩阵的行，另一个遍历每一行的项。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply_matrix_vector(matrix, vector):\n",
    "  return tuple(\n",
    "    sum(vector_entry * matrix_entry \n",
    "        for vector_entry, matrix_entry in zip(row, vector)) ## 循环列\n",
    "    for row in matrix ## 循环行\n",
    "  )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2x2矩阵测试:\n",
      "矩阵: ((1, 2), (3, 4))\n",
      "向量: (5, 6)\n",
      "结果: (17, 39)\n"
     ]
    }
   ],
   "source": [
    "# 测试1：2x2矩阵与2维向量相乘\n",
    "matrix_2x2 = (\n",
    "    (1, 2),\n",
    "    (3, 4)\n",
    ")\n",
    "vector_2d = (5, 6)\n",
    "\n",
    "result_2d = multiply_matrix_vector(matrix_2x2, vector_2d)\n",
    "print(\"2x2矩阵测试:\")\n",
    "print(f\"矩阵: {matrix_2x2}\")\n",
    "print(f\"向量: {vector_2d}\")\n",
    "print(f\"结果: {result_2d}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.8:利用输出坐标是输入矩阵行与输入向量的点积这一事实，用另一种方式实现multiply_matrix_vector()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply_matrix_vector_dot(matrix, vector):\n",
    "  return tuple(\n",
    "    dot(row, vector)\n",
    "    for row in matrix\n",
    "  )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2x2矩阵测试:\n",
      "矩阵: ((1, 2), (3, 4))\n",
      "向量: (5, 6)\n",
      "结果: (17, 39)\n"
     ]
    }
   ],
   "source": [
    "# 测试1：2x2矩阵与2维向量相乘\n",
    "matrix_2x2 = (\n",
    "    (1, 2),\n",
    "    (3, 4)\n",
    ")\n",
    "vector_2d = (5, 6)\n",
    "\n",
    "result_2d = multiply_matrix_vector_dot(matrix_2x2, vector_2d)\n",
    "print(\"2x2矩阵测试:\")\n",
    "print(f\"矩阵: {matrix_2x2}\")\n",
    "print(f\"向量: {vector_2d}\")\n",
    "print(f\"结果: {result_2d}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.9(小项目):我首先告诉了你什么是线性变换，然后展示了任意线性变换都可以用矩阵来表示。现在来证明相反的事实:所有矩阵都表示线性变换。从二维向量乘以2x2矩阵或三维向量乘以3x3矩阵的显式公式开始，用代数法证明这一点。也就是说，证明矩阵乘法前后，向量和与标量乘积保持不变。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 二维证明\n",
    "$$\n",
    "设： A = \n",
    "\\begin{pmatrix}\n",
    "a & b \\\\\n",
    "c & d\n",
    "\\end{pmatrix}，\n",
    "\n",
    "u = \n",
    "\\begin{pmatrix}\n",
    "u_1 \\\\\n",
    "u_2\n",
    "\\end{pmatrix}，\n",
    "\n",
    "v = \n",
    "\\begin{pmatrix}\n",
    "v_1 \\\\\n",
    "v_2\n",
    "\\end{pmatrix}，\n",
    "\n",
    "有Au和Av：\n",
    "Au =\n",
    "\\begin{pmatrix}\n",
    "a & b \\\\\n",
    "c & d\n",
    "\\end{pmatrix}\n",
    "\\begin{pmatrix}\n",
    "u_1 \\\\\n",
    "u_2\n",
    "\\end{pmatrix},\n",
    "\n",
    "Av =\n",
    "\\begin{pmatrix}\n",
    "a & b \\\\\n",
    "c & d\n",
    "\\end{pmatrix}\n",
    "\\begin{pmatrix}\n",
    "v_1 \\\\\n",
    "v_2\n",
    "\\end{pmatrix}\n",
    "$$\n",
    "计算Au+Av和A(u+v)：\n",
    "$$\n",
    "\n",
    "1. Au+Av：\n",
    "\\begin{pmatrix}\n",
    "au_1 + bu_2 \\\\\n",
    "cu_2 + du_2\n",
    "\\end{pmatrix}\n",
    "+\n",
    "\\begin{pmatrix}\n",
    "av_1 + bv_2 \\\\\n",
    "cv_2 + dv_2\n",
    "\\end{pmatrix} =\n",
    "\\begin{pmatrix}\n",
    "au_1 + bu_2 + av_1 + bv_2 \\\\\n",
    "cu_2 + du_2 + cv_2 + dv_2\n",
    "\\end{pmatrix}\n",
    "$$\n",
    "$$\n",
    "2. A(u+v):\n",
    "\\begin{pmatrix}\n",
    "a & b \\\\\n",
    "c & d\n",
    "\\end{pmatrix} + \n",
    "\\begin{pmatrix}\n",
    "u_1 + v_1 \\\\\n",
    "u_2 + v_2\n",
    "\\end{pmatrix} =\n",
    "\\begin{pmatrix}\n",
    "a(u_1 + v_1) + b(u_2 + v_2) \\\\\n",
    "c(u_1 + v_1) + d(u_2 + v_2)\n",
    "\\end{pmatrix} = \n",
    "\\begin{pmatrix}\n",
    "au_1 + bu_2 + av_1 + bv_2 \\\\\n",
    "cu_2 + du_2 + cv_2 + dv_2\n",
    "\\end{pmatrix}\n",
    "\n",
    "\n",
    "\n",
    "$$\n",
    "2. 同理任意数s也是如此\n",
    "$$\n",
    "sv = \n",
    "\\begin{pmatrix}\n",
    "su_1 \\\\\n",
    "su_2 \n",
    "\\end{pmatrix}\n",
    ",\n",
    "s(Av) = \n",
    "\\begin{pmatrix}\n",
    "s(av_1 + bv_2) \\\\\n",
    "s(cv_2 + dv_2)\n",
    "\\end{pmatrix}\n",
    "=\n",
    "\\begin{pmatrix}\n",
    "(sav_1 + sbv_2) \\\\\n",
    "(scv_2 + sdv_2)\n",
    "\\end{pmatrix}\n",
    ",\n",
    "A(sv) = \n",
    "\\begin{pmatrix}\n",
    "a(sv_1) + b(sv_2) \\\\\n",
    "c(sv_2) + d(sv_2)\n",
    "\\end{pmatrix}\n",
    "=\n",
    "\\begin{pmatrix}\n",
    "(sav_1 + sbv_2) \\\\\n",
    "(scv_2 + sdv_2)\n",
    "\\end{pmatrix}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.10:再一次使用5.1.3节中的两个矩阵。\n",
    "\n",
    "$\\left|\\boldsymbol{A}=\\left(\n",
    "\\begin{array}\n",
    "{ccc}{1} & {1} & {0} \\\\\n",
    "{1} & {0} & {1} \\\\\n",
    "{1} & {-1} & {1}\n",
    "\\end{array}\\right.\\right),\\quad\\boldsymbol{B}=\n",
    "\\begin{pmatrix}\n",
    "{0} & {2} & {1} \\\\\n",
    "{0} & {1} & {0} \\\\\n",
    "{1} & {0} & {-1}\n",
    "\\end{pmatrix}$\n",
    "\n",
    "实现函数compose_a_b，执行A的线性变换和 B的线性变换的组合，然后用本节前面练习中的infer_matrix函数来证明infer_matrix(3,compose_a_b)与矩阵积AB相同。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其实就是为了证明用两个矩阵对标准基做线性变换后得到的结果和两个矩阵直接做线性变换后得到的结果是否一样的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transforms import compose, multiply_matrix_vector\n",
    "a = ((1,1,0),(1,0,1),(1,-1,1))\n",
    "b = ((0,2,1),(0,1,0),(1,0,-1))\n",
    "\n",
    "def transform_a(v):\n",
    "  return multiply_matrix_vector(a,v)\n",
    "\n",
    "def transform_b(v):\n",
    "  return multiply_matrix_vector(b,v)\n",
    "\n",
    "compose_a_b = compose(transform_a,transform_b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((0, 3, 1), (1, 2, 0), (1, 1, 0))\n",
      "((0, 3, 1), (1, 2, 0), (1, 1, 0))\n"
     ]
    }
   ],
   "source": [
    "## 用两个矩阵对标准基做线性变换\n",
    "print(infer_matrix(3,compose_a_b))\n",
    "\n",
    "## 两个矩阵直接做线性变换\n",
    "print(matrix_multiply(a,b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.11(小项目):找出两个2x2矩阵，它们都不是单位矩阵$I_2$，但其乘积是单位矩阵。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "\\begin{pmatrix}\n",
    "0 & 1 \\\\\n",
    "-1 & 0\n",
    "\\end{pmatrix}\n",
    "\\begin{pmatrix}\n",
    "0 & -1 \\\\\n",
    "1 & 0\n",
    "\\end{pmatrix} = \n",
    "\\begin{pmatrix}\n",
    "1 & 0 \\\\\n",
    "0 & 1\n",
    "\\end{pmatrix}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "练习5.12:方阵可以与自身相乘任意次数。可以把连续的矩阵乘法看作“取一个矩阵的幂”。对于方阵A，可以把 AA写成$A^2$，把AAA写成$A^3$，以此类推。实现matrix_power(power，matrix)函数，取指定整数的矩阵的幂。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "def matrix_power(power,matrix):\n",
    "  result = matrix\n",
    "  for _ in range(1,power):\n",
    "    result = matrix_multiply(result,matrix)\n",
    "  return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试1：单位矩阵的幂\n",
      "单位矩阵: ((1, 0), (0, 1))\n",
      "单位矩阵的2次幂: ((1, 0), (0, 1))\n",
      "单位矩阵的5次幂: ((1, 0), (0, 1))\n",
      "\n",
      "测试2：旋转矩阵的幂\n",
      "90度旋转矩阵: ((0, -1), (1, 0))\n",
      "180度旋转矩阵 (90度旋转的2次幂): ((-1, 0), (0, -1))\n",
      "360度旋转矩阵 (90度旋转的4次幂): ((1, 0), (0, 1))\n",
      "\n",
      "测试3：一般矩阵的幂\n",
      "原始矩阵: ((2, 1), (1, 3))\n",
      "矩阵的2次幂: ((5, 5), (5, 10))\n",
      "矩阵的3次幂: ((15, 20), (20, 35))\n",
      "\n",
      "测试4：边界情况 - 1次幂\n",
      "原始矩阵: ((2, 1), (1, 3))\n",
      "矩阵的1次幂: ((2, 1), (1, 3))\n"
     ]
    }
   ],
   "source": [
    "# 测试1：单位矩阵的幂\n",
    "print(\"测试1：单位矩阵的幂\")\n",
    "identity_2x2 = (\n",
    "    (1, 0),\n",
    "    (0, 1)\n",
    ")\n",
    "print(f\"单位矩阵: {identity_2x2}\")\n",
    "print(f\"单位矩阵的2次幂: {matrix_power(2, identity_2x2)}\")\n",
    "print(f\"单位矩阵的5次幂: {matrix_power(5, identity_2x2)}\")\n",
    "print()\n",
    "\n",
    "# 测试2：旋转矩阵的幂\n",
    "print(\"测试2：旋转矩阵的幂\")\n",
    "rotation_90 = (\n",
    "    (0, -1),\n",
    "    (1, 0)\n",
    ")\n",
    "print(f\"90度旋转矩阵: {rotation_90}\")\n",
    "print(f\"180度旋转矩阵 (90度旋转的2次幂): {matrix_power(2, rotation_90)}\")\n",
    "print(f\"360度旋转矩阵 (90度旋转的4次幂): {matrix_power(4, rotation_90)}\")\n",
    "print()\n",
    "\n",
    "# 测试3：一般矩阵的幂\n",
    "print(\"测试3：一般矩阵的幂\")\n",
    "matrix_2x2 = (\n",
    "    (2, 1),\n",
    "    (1, 3)\n",
    ")\n",
    "print(f\"原始矩阵: {matrix_2x2}\")\n",
    "print(f\"矩阵的2次幂: {matrix_power(2, matrix_2x2)}\")\n",
    "print(f\"矩阵的3次幂: {matrix_power(3, matrix_2x2)}\")\n",
    "print()\n",
    "\n",
    "# 测试4：边界情况 - 1次幂\n",
    "print(\"测试4：边界情况 - 1次幂\")\n",
    "print(f\"原始矩阵: {matrix_2x2}\")\n",
    "print(f\"矩阵的1次幂: {matrix_power(1, matrix_2x2)}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3.8",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
